#include "Protocol_CAN.h"

#include "aes.h"
#include "Bsp_adc.h"
#include "Bsp_can.h"
#include "Bsp_dac.h"
#include "debug.h"
#include "Dev_manage.h"
#include "fifo.h"
#include "msg_buf.h"
#include "ntc.h"
#include "sys_lib.h"
#include "tick.h"
#include "Version.h"

#include <string.h>

#define COMPENSATION_REDUCE_COEFFICIENT 0.98 /* 补偿点下调系数 */

void read_comp_config(sensor_point_info_t *sensor_info);

static uint8_t GetNodeID(void);
static int     generate_random_int(int min, int max);
static void    comp_handle(uint8_t point_idx, sensor_point_info_t *sensor_info);
static void    get_sensor_type(sensor_point_info_t *sensor_info);
static bool    comp_judge(uint8_t point_idx, sensor_point_info_t *sensor_info);
static void    get_comp_ref(uint8_t point_idx, sensor_point_info_t *sensor_info);
static float   comp_output_handle(uint8_t row_i, const sensor_point_info_t *sensor_info);
static float   cal_conductance(uint8_t row_i, const sensor_point_info_t *sensor_info);
static float   cal_pressure(uint8_t row_i, float conductance, const sensor_point_info_t *sensor_info);
static float   cal_random_pressure(float pressure);
static void    set_frame_head_data(CanMultiFramePacket_t *can_packet_data);
static void    cal_aes_key(void);
static bool    verify_comp_config_data_valid(uint8_t *flash_data, uint16_t data_len);
static bool    verify_flash_data_valid(uint8_t *flash_data, uint16_t data_len);
// static bool    verify_point_num_valid(uint8_t *flash_data, uint16_t data_len);
// static bool    verify_comp_num_valid(uint8_t *flash_data, uint16_t data_len);
static void    comp_config_data_assemble(uint8_t *flash_data, uint16_t data_len,
                                         sensor_point_info_t *sensor_info);
static void    output_data_sort(void);

CanMultiFramePacket_t can_packet_data;

sensor_point_info_t sensor_info; /* 传感器点信息 */

extern uint8_t                data_format;
extern Res2Press_Conversion_t res_conv_data[];

static bool is_read = true;

/* 补偿点位置 */
static uint8_t comp_points[] = { 3, 10 };

/**
 * @brief 函数主要作用：
 *          1. 收集传感器矩阵的原始数据
 *          2. 根据配置进行数据转换（压力值或电阻值）
 *
 */
void update_sub_data()
{
    uint8_t  i        = 0;
    uint32_t Res_Data = 0;

    /* 设置帧头数据 */
    set_frame_head_data(&can_packet_data);

    /* 初始化随机数生成器 */
    srand(rt_tick_get());

    /* 读取补偿点配置 */
    if (is_read) {
        read_comp_config(&sensor_info);
        is_read = false;
    }

    /* 遍历整个传感器矩阵（ROW_MAX × COLUMN_MAX）, 对每个传感器点进行处理 */
    for (i = 0; i < ROW_MAX; i++) {
        for (uint8_t j = 0; j < COLUMN_MAX; j++) {

            /* 湿补点处理 */
            comp_handle(j, &sensor_info);

            Res_Data = (res_data_arr[i * COLUMN_MAX + j].Res_value);
            LOG("res src data: [%hhu]-%u\n", j, Res_Data);

            /* 0压力时不进行补偿处理 */
            if (Res_Data != RES_VALUE_INVALID) {
                Res_Data *= compensation.coefficient;
            }

            // 计算电导值
            float Res_conduction = 0;
            float press_val_cal  = 0;
            if (Res_Data > RES_VALUE_MIN_ERR) {
                Res_conduction = 1E6 / Res_Data;
            }

            /* 数据输出格式类型为1 -> 输出电阻 */
            if (can_packet_data.data_format) { // 压力输出

                if (Res_Data >= RES_VALUE_INVALID) {
                    // can_packet_data.res[i][j] = 0;
                    press_val_cal = 0;
                }
                else if (sensor_info.is_comp_point) {
                    press_val_cal = comp_output_handle(i, &sensor_info);
                }
                /* 根据电阻值范围使用不同的二次方程系数计算压力值 */
                else if (!sensor_info.is_comp_point &&
                         Res_Data > res_conv_data[j].resistanceThreshold * 10) {
                    press_val_cal = (res_conv_data[j].coefficient[0].a * Res_conduction * Res_conduction +
                                     res_conv_data[j].coefficient[0].b * Res_conduction +
                                     res_conv_data[j].coefficient[0].c) *
                                    10;
                }
                else if (!sensor_info.is_comp_point && Res_Data > RES_VALUE_MIN_ERR) {
                    press_val_cal = (res_conv_data[j].coefficient[1].a * Res_conduction * Res_conduction +
                                     res_conv_data[j].coefficient[1].b * Res_conduction +
                                     res_conv_data[j].coefficient[1].c) *
                                    10;
                }
                else {
                    // 阻值过小的异常
                    // can_packet_data.res[i][j] = 0XFFFF;
                    press_val_cal = 0;
                }
                // 压力填充
                if (press_val_cal < 0.5) {
                    can_packet_data.res[i][j] = 0;
                }
                else if (press_val_cal < 65000) {
                    can_packet_data.res[i][j] = (uint16_t)(press_val_cal + 0.5);
                }
                else { // 压力值过大时做限制，避免解析溢出
                    can_packet_data.res[i][j] = 65000;
                }
            }
            else { // 阻值输出
                can_packet_data.res[i][j] = (uint16_t)(Res_Data / 10);
            }
        }
    }

    /* 对输出的数据排序（电阻/压力），补偿点移动到13和14号，其余点位往前补位 */
    output_data_sort();

    /* CRC校验 */
    can_packet_data.crc = Syslib_CalCrcTable((uint8_t *)&can_packet_data,
                                             sizeof(CanMultiFramePacket_t) - sizeof(can_packet_data.crc));
}

void SplitAndEnqueueCanPacket(uint8_t *src, uint16_t len)
{
    int         i = 0;
    CAN_Frame_t tmp_frame;
    uint16_t    frame_cnt = (len + 6) / 7;

    if (FIFO_QueueGetFreeDepth(&can_send_queue) < frame_cnt) {
        // XXX:添加提示信息
        return;
    }

    uint8_t  encrypt_data[len];
    uint32_t encrypt_len = len;

    if (is_data_encrypt) {
        /* 计算密钥 */
        cal_aes_key();

        /* src数据加密 */
        AES_EncryptionAndDecryption(aes_key_buf, 16, aes_ivr_buf, src, len, encrypt_data, &encrypt_len);

        /* 数据加密成功 */
        if (encrypt_len == len) {
            tmp_frame.std_id = CAN_ENCRYPT_BASE_ID + Dev_GetNodeID();
        }
        else {
            /* 数据加密失败，使用原始数据和明文ID */
            memcpy(encrypt_data, src, len);
            encrypt_len = len;
            LOG("encrypt_len != len, fallback to plain data\n");
            tmp_frame.std_id = 0X310 + Dev_GetNodeID();
        }
    }
    else {
        /* 不加密，直接复制原始数据 */
        memcpy(encrypt_data, src, len);
        encrypt_len      = len;
        tmp_frame.std_id = 0X310 + Dev_GetNodeID();
    }

    // 一包数据打包5帧CAN数据
    for (i = 0; i < frame_cnt; i++) {
        tmp_frame.data.byte[0] = SUB_DATA_FRAME + i;
        if (len >= 7) {
            memcpy(&tmp_frame.data.byte[1], encrypt_data + 7 * i, 7);
            len -= 7;
        }
        else {
            memset(&tmp_frame.data.byte[1], 0, 7);
            memcpy(&tmp_frame.data.byte[1], encrypt_data + 7 * i, len);
            len = 0;
        }

        FIFO_QueuePush(&can_send_queue, tmp_frame);
        // XXX:获取push结果
    }
}

/**
 * @brief  向CAN发送队列中准备数据
 * @note
 * @retval None
 */
void CANFrameSend_getdata()
{
    Msg_S msg;                                               // 消息结构体
    update_sub_data();                                       // 更新订阅数据(更新传感器数据)
    SplitAndEnqueueCanPacket((uint8_t *)&can_packet_data,
                             sizeof(CanMultiFramePacket_t)); // 将订阅数据编码成CAN帧格式
    // 从诊断fifo中获取数据

    /* 如果从发送缓冲区获取数据成功 */
    if (0 == GetFromTxBuf(&msg)) {
        CAN_Frame_t tmp_frame;
        tmp_frame.std_id = msg.id;
        tmp_frame.dlc    = 8;
        memcpy(tmp_frame.data.byte, msg.data, 8);

        // 将帧推入发送队列
        FIFO_QueuePush(&can_send_queue, tmp_frame);
    }
}

/**
 * @brief  从CAN队列取出数据向总线发送
 * @note
 * @retval None
 */
void canFrameSend_Handle()
{
    CAN_Frame_t can_frame; // 定义一个消息帧结构体，用于存储要发送的CAN帧
    bool        ret;       // 定义返回值变量，用于存储函数调用结果

    /* CAN总线就绪检查 */
    ret = Bsp_get_CAN_Tx_Ready(); // 检查CAN总线是否就绪可发送
    if (ret == false) {
        // CAN总线未就绪，先不发
        return;
    }

    /* 从发送队列获取数据 */
    ret = FIFO_QueuePop(&can_send_queue, &can_frame);
    if (ret == false) {
        return;
    }

    /* 发送数据 */
    Bsp_CAN_FIFO_Write(can_frame.std_id, 8, can_frame.data.byte);
}

/**
 * @brief 读取补偿点信息
 *
 * @param sensor_info
 */
void read_comp_config(sensor_point_info_t *sensor_info)
{
    uint8_t flash_data[COMP_CONFIG_INFO_COUNT] = { 0 };

    /* 校验数据是否有效 */
    if (!verify_comp_config_data_valid(flash_data, COMP_CONFIG_INFO_COUNT)) {
        LOG("read comp config data fail\n");
        sensor_info->comp_config.is_config = false;
        return;
    }

    /* 装配数据 */
    comp_config_data_assemble(flash_data, COMP_CONFIG_INFO_COUNT, sensor_info);
}

/**
 * @brief 对输出的数据排序（电阻/压力）
 *
 */
static void output_data_sort(void)
{
    uint16_t tmp_cell[COLUMN_MAX] = { 0 };
    memcpy(tmp_cell, can_packet_data.res[0], sizeof(uint16_t) * COLUMN_MAX);

    uint8_t src_indices[] = { 0, 1, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13 };
    for (uint8_t i = 0; i < sizeof(src_indices) / sizeof(src_indices[0]); ++i) {
        can_packet_data.res[0][i] = tmp_cell[src_indices[i]];
    }

    /* 最后两个: 3号点和10号点 */
    can_packet_data.res[0][COLUMN_MAX - 1 - 1] = tmp_cell[comp_points[0] - 1];
    can_packet_data.res[0][COLUMN_MAX - 1]     = tmp_cell[comp_points[1] - 1];
}

/**
 * @brief 装配补偿配置数据
 *
 * @param flash_data    flash数据
 * @param data_len      数据长度
 * @param sensor_info   传感器信息结构体指针
 */
static void comp_config_data_assemble(uint8_t *flash_data, uint16_t data_len,
                                      sensor_point_info_t *sensor_info)
{
    if (flash_data == NULL || data_len == 0) {
        LOG("Invalid input parameters\n");
        return;
    }

    sensor_info->comp_config.point_num                = flash_data[COMP_CONFIG_POINT_NUM_POS];
    sensor_info->comp_config.start_num                = flash_data[COMP_CONFIG_START_SER_NUM_POS];
    sensor_info->comp_config.comp_point_count         = flash_data[COMP_CONFIG_COMP_NUM_POS];
    sensor_info->comp_config.comp_point_arr[0]        = flash_data[COMP_CONFIG_COMP_POINT_1_POS] - 1;
    sensor_info->comp_config.comp_point_arr[1]        = flash_data[COMP_CONFIG_COMP_POINT_2_POS] - 1;
    sensor_info->comp_config.ref_point_arr[0]         = flash_data[COMP_CONFIG_COMP_REF_POINT_1_POS] - 1;
    sensor_info->comp_config.ref_point_arr[1]         = flash_data[COMP_CONFIG_COMP_REF_POINT_2_POS] - 1;
    sensor_info->comp_config.flag                     = flash_data[COMP_CONFIG_FLAG_POS];
    sensor_info->comp_config.is_config                = true;
    sensor_info->comp_config.sensor_point_section.min = flash_data[COMP_CONFIG_START_SER_NUM_POS];
    sensor_info->comp_config.sensor_point_section.max =
        flash_data[COMP_CONFIG_START_SER_NUM_POS] + flash_data[COMP_CONFIG_START_SER_NUM_POS] - 1;
}

/**
 * @brief 校验补偿配置数据是否有效
 *
 * @param flash_data    存储flash数据的缓冲区
 * @param data_len      flash数据的长度
 * @return true         数据有效
 * @return false        数据无效
 */
static bool verify_comp_config_data_valid(uint8_t *flash_data, uint16_t data_len)
{
    /* 读取flash数据 */
    if (VME2P_Read(VM_INDEX_COMP_CONFIG, flash_data, COMP_CONFIG_INFO_COUNT) != COMP_CONFIG_INFO_COUNT) {
        LOG("read flash data fail\n");
        return false;
    }

    /* 校验flash中是否有数据, 即验证flag */
    if (!verify_flash_data_valid(flash_data, data_len)) {
        LOG("flash data is not valid\n");
        return false;
    }

    return true;
}

/**
 * @brief 验证flash数据是否有效
 *
 * @param flash_data    flash数据
 * @param data_len      flash数据长度
 * @return true         数据有效
 * @return false        数据无效
 */
static bool verify_flash_data_valid(uint8_t *flash_data, uint16_t data_len)
{
    if (flash_data == NULL || data_len == 0) {
        LOG("Invalid input parameters\n");
        return false;
    }

    /* 验证flag */
    if (flash_data[COMP_CONFIG_FLAG_POS] != COMP_CONFIG_WRITE_FLAG) {
        LOG("Invalid flag\n");
        return false;
    }

    return true;
}

/**
 * @brief 计算aes密钥
 *
 */
static void cal_aes_key(void)
{
    uint32_t can_encrypt_id = CAN_ENCRYPT_BASE_ID + Dev_GetNodeID();

    // key[0~3] = ~(uint32_t) CAN_ENCRYPT_ID (取反)
    uint32_t inverted_id = ~can_encrypt_id;
    aes_key_buf[0]       = (uint8_t)(inverted_id & 0xFF);
    aes_key_buf[1]       = (uint8_t)((inverted_id >> 8) & 0xFF);
    aes_key_buf[2]       = (uint8_t)((inverted_id >> 16) & 0xFF);
    aes_key_buf[3]       = (uint8_t)((inverted_id >> 24) & 0xFF);

    // key[4~7] = (uint32_t) CAN_ENCRYPT_ID (原值)
    aes_key_buf[4] = (uint8_t)(can_encrypt_id & 0xFF);
    aes_key_buf[5] = (uint8_t)((can_encrypt_id >> 8) & 0xFF);
    aes_key_buf[6] = (uint8_t)((can_encrypt_id >> 16) & 0xFF);
    aes_key_buf[7] = (uint8_t)((can_encrypt_id >> 24) & 0xFF);

    // key[8~15] = 0
    for (int i = 8; i < 16; i++) {
        aes_key_buf[i] = 0;
    }
}

/**
 * @brief 获取NodeID
 * @return 成功返回id, 失败返回0
 */
static uint8_t GetNodeID(void)
{
    uint8_t nodeId = 0;
    if (Dev_ReadNodeID(&nodeId) == 0) return 0;
    return nodeId;
}

/**
 * @brief 生成指定区间内的随机整数
 * @param min 区间最小值（包含）
 * @param max 区间最大值（包含）
 * @return 区间内的随机整数
 */
static int generate_random_int(int min, int max)
{
    // 确保随机数生成器已初始化
    static bool is_initialized = false;
    if (!is_initialized) {
        srand(rt_tick_get()); // 使用当前时间作为种子
        is_initialized = true;
    }

    // 生成随机整数
    int random_int = min + rand() % (max - min + 1);
    return random_int;
}

/**
 * @brief 处理补偿点
 *
 * @param point_idx     传感点索引, 从0开始
 * @param sensor_info   传感点信息
 */
static void comp_handle(uint8_t point_idx, sensor_point_info_t *sensor_info)
{
    /* 获取传感器类型 */
    get_sensor_type(sensor_info);

    /* 判断是否是补偿点 */
    if (!comp_judge(point_idx, sensor_info)) return;

    /* 获取湿补点的参考点 */
    get_comp_ref(point_idx, sensor_info);
}

/**
 * @brief 获取传感点类型
 *
 * @param sensor_info   传感点信息
 */
static void get_sensor_type(sensor_point_info_t *sensor_info)
{
    /* 获取采集器id */
    uint8_t node_id = GetNodeID();
    if (!node_id) {
        sensor_info->sensor_type = SENSOR_TYPE_UNKNOWN;
        return;
    }
    else {
        sensor_info->node_id = (Node_ID_e)node_id;
    }

    /* 使用查找表快速映射节点ID到传感器类型 */
    static const Sensor_Type_e sensor_type_map[] = {
        /* LK1A */
        [NODE_ID_LK1A_LEG]    = SENSOR_TYPE_LK1A,
        [NODE_ID_LK1A_LUMBAR] = SENSOR_TYPE_LK1A,
        [NODE_ID_LK1A_RIGHT]  = SENSOR_TYPE_LK1A,
        [NODE_ID_LK1A_LEFT]   = SENSOR_TYPE_LK1A,
        /* PK1B */
        [NODE_ID_PK1B_BACK]   = SENSOR_TYPE_PK1B,
        [NODE_ID_PK1B_LEG]    = SENSOR_TYPE_PK1B,
        [NODE_ID_PK1B_LUMBAR] = SENSOR_TYPE_PK1B,
        [NODE_ID_PK1B_RIGHT]  = SENSOR_TYPE_PK1B,
        [NODE_ID_PK1B_LEFT]   = SENSOR_TYPE_PK1B,
    };
    static const size_t sensor_type_map_size = sizeof(sensor_type_map) / sizeof(sensor_type_map[0]);

    if (sensor_info->node_id < sensor_type_map_size) {
        sensor_info->sensor_type = sensor_type_map[sensor_info->node_id];
    }
    else {
        sensor_info->sensor_type = SENSOR_TYPE_UNKNOWN;
    }
}

/**
 * @brief  补偿点判断，根据id来判断
 *
 * @param point_idx    传感点索引, 从0开始
 * @param sensor_info  传感点信息
 * @return true        是补偿点
 * @return false       不是补偿点
 */
static bool comp_judge(uint8_t point_idx, sensor_point_info_t *sensor_info)
{
    if (!sensor_info) return false;

    /* 如果CAN诊断配置了湿补点 */
    if (sensor_info->comp_config.is_config) {
        for (uint8_t i = 0; i < sensor_info->comp_config.comp_point_count; ++i) {
            /* 只要是配置的湿补点其中的一个就返回true */
            if (sensor_info->comp_config.comp_point_arr[i] == point_idx) {
                LOG("comp point idx:%d, point_idx: %d\n", sensor_info->comp_config.comp_point_arr[i],
                    point_idx);
                sensor_info->is_comp_point = true;
                return true;
            }
        }

        sensor_info->is_comp_point = false;
        return false;
    }

    static bool initialized                                 = false; // 标志位，用于判断是否已经初始化
    static bool comp_map[NODE_ID_MAX][SENSOR_POINT_MAXSIZE] = { { false } }; // 补偿点映射表[id][point_idx]

    if (!initialized) {
        /* LK1A */
        comp_map[NODE_ID_LK1A_LEG][COMP_POINT_LK1A_LEG_L]     = true;
        comp_map[NODE_ID_LK1A_LEG][COMP_POINT_LK1A_LEG_R]     = true;
        comp_map[NODE_ID_LK1A_LUMBAR][COMP_POINT_LK1A_LUMBAR] = true;
        comp_map[NODE_ID_LK1A_RIGHT][COMP_POINT_LK1A_RIGHT]   = true;
        comp_map[NODE_ID_LK1A_LEFT][COMP_POINT_LK1A_LEFT]     = true;

        /* PK1B */
        comp_map[NODE_ID_PK1B_BACK][COMP_POINT_PK1B_BACK]     = true;
        comp_map[NODE_ID_PK1B_LEG][COMP_POINT_PK1B_LEG_L]     = true;
        comp_map[NODE_ID_PK1B_LEG][COMP_POINT_PK1B_LEG_R]     = true;
        comp_map[NODE_ID_PK1B_LUMBAR][COMP_POINT_PK1B_LUMBAR] = true;
        comp_map[NODE_ID_PK1B_RIGHT][COMP_POINT_PK1B_RIGHT]   = true;
        comp_map[NODE_ID_PK1B_LEFT][COMP_POINT_PK1B_LEFT]     = true;

        initialized = true;
    }

    if (sensor_info->node_id <= NODE_ID_MAX && point_idx <= SENSOR_POINT_MAXSIZE) {
        sensor_info->is_comp_point = comp_map[sensor_info->node_id][point_idx];
        return sensor_info->is_comp_point;
    }

    // 针对于不在范围内的情况，返回false
    sensor_info->is_comp_point = false;
    return sensor_info->is_comp_point;
}

/**
 * @brief 获取湿补点的参考点
 *
 * @param point_idx       传感点索引, 从0开始
 * @param sensor_info     传感点信息
 */
static void get_comp_ref(uint8_t point_idx, sensor_point_info_t *sensor_info)
{
    if (!sensor_info) return;

    /* 根据是否CAN诊断写入了湿补点配置 */
    if (sensor_info->comp_config.is_config) {
        /* 不等于腿托，则都按照一个湿补点来 */
        if (sensor_info->comp_config.comp_point_count != COMP_AND_REF_POINT_MAXSIZE) {
            sensor_info->comp_ref_point = sensor_info->comp_config.ref_point_arr[0];
            LOG("comp_ref: %d\n", sensor_info->comp_ref_point);
            return;
        }

        /* 等于腿托 */
        for (uint8_t i = 0; i < sensor_info->comp_config.comp_point_count; ++i) {
            if (sensor_info->comp_config.comp_point_arr[i] == point_idx) {
                sensor_info->comp_ref_point = sensor_info->comp_config.ref_point_arr[i];
                return;
            }
        }

        return;
    }

    const uint8_t ref_point_table[] = {
        /* LK1A */
        [NODE_ID_LK1A_LUMBAR] = COMP_REF_POINT_LK1A_LUMBAR,
        [NODE_ID_LK1A_RIGHT]  = COMP_REF_POINT_LK1A_RIGHT,
        [NODE_ID_LK1A_LEFT]   = COMP_REF_POINT_LK1A_LEFT,

        /* PK1B */
        [NODE_ID_PK1B_BACK]   = COMP_REF_POINT_PK1B_BACK,
        [NODE_ID_PK1B_LUMBAR] = COMP_REF_POINT_PK1B_LUMBAR,
        [NODE_ID_PK1B_RIGHT]  = COMP_REF_POINT_PK1B_RIGHT,
        [NODE_ID_PK1B_LEFT]   = COMP_REF_POINT_PK1B_LEFT,
    };

    /* 填充非腿托传感器的参考点 */
    if (sensor_info->node_id != NODE_ID_LK1A_LEG && sensor_info->node_id != NODE_ID_PK1B_LEG) {
        sensor_info->comp_ref_point = ref_point_table[sensor_info->node_id];
        return;
    }

    if (point_idx == COMP_POINT_LK1A_LEG_L) {
        sensor_info->comp_ref_point = COMP_REF_POINT_LK1A_LEG_L;
    }
    else if (point_idx == COMP_POINT_LK1A_LEG_R) {
        sensor_info->comp_ref_point = COMP_REF_POINT_LK1A_LEG_R;
    }
    else if (point_idx == COMP_POINT_PK1B_LEG_L) {
        sensor_info->comp_ref_point = COMP_REF_POINT_PK1B_LEG_L;
    }
    else if (point_idx == COMP_POINT_PK1B_LEG_R) {
        sensor_info->comp_ref_point = COMP_REF_POINT_PK1B_LEG_R;
    }
}

/**
 * @brief
 *
 * @param row_i
 * @param sensor_info
 * @return float
 */
static float comp_output_handle(uint8_t row_i, const sensor_point_info_t *sensor_info)
{
    /* 计算电导值 */
    float conductance = cal_conductance(row_i, sensor_info);

    /* 计算压力值 */
    float pressure = cal_pressure(row_i, conductance, sensor_info);

    /* 计算输出值 */
    float random_pressure = cal_random_pressure(pressure);

    return random_pressure;
}

/**
 * @brief  计算电导值
 *
 * @param row_i         矩阵行号
 * @param sensor_info   传感器信息
 * @return float        电导值
 */
static float cal_conductance(uint8_t row_i, const sensor_point_info_t *sensor_info)
{
    float conductance = 0.0f;
    float ref_res_val = res_data_arr[row_i * COLUMN_MAX + sensor_info->comp_ref_point].Res_value;

    if (ref_res_val < RES_VALUE_INVALID && ref_res_val > RES_VALUE_MIN_ERR) {
        conductance = 1E6 / ref_res_val;
    }

    return conductance;
}

/**
 * @brief   计算传感点压力值
 *
 * @param row_i         行号
 * @param sensor_info   传感点信息
 * @return float        压力值
 */
static float cal_pressure(uint8_t row_i, float conductance, const sensor_point_info_t *sensor_info)
{
    if (conductance == 0.0f) {
        return 0.0f;
    }

    float pressure = 0.0f;

    uint8_t cofft_idx =
        (res_data_arr[row_i * COLUMN_MAX + sensor_info->comp_ref_point].Res_value >
         res_conv_data[sensor_info->comp_ref_point].resistanceThreshold * sensor_info->comp_ref_point)
            ? 0
            : 1;

    pressure =
        (res_conv_data[sensor_info->comp_ref_point].coefficient[cofft_idx].a * conductance * conductance +
         res_conv_data[sensor_info->comp_ref_point].coefficient[cofft_idx].b * conductance +
         res_conv_data[sensor_info->comp_ref_point].coefficient[cofft_idx].c) *
        10;

    return pressure;
}

/**
 * @brief   计算随机压力
 *
 * @param pressure      压力值
 * @return float        随机压力值
 */
static float cal_random_pressure(float pressure)
{
    float random_pressure = pressure * (generate_random_int(45, 50) / 100.0f);

    return random_pressure;
}

/**
 * @brief 设置帧头数据
 *
 * @param can_packet_data   can packet obj
 */
static void set_frame_head_data(CanMultiFramePacket_t *can_packet_data)
{
    can_packet_data->can_protol_ver = CAN_PROTOL_VER; // 设置CAN协议版本
    can_packet_data->data_format    = !!data_format;  // 设置数据输出格式0 or 1
    can_packet_data->soft_ver       = SOFT_VER_X * 100 + SOFT_VER_Y * 10 + SOFT_VER_Z; // 设置软件版本号
    can_packet_data->row            = ROW_MAX;                                         // 设置矩阵行数
    can_packet_data->column         = COLUMN_MAX;                                      // 设置矩阵列数

    // can_packet_data.temp = (int8_t)(TEMP_Value + 0.5); // 四舍五入
    // 温度数据更新
    // can_packet_data->temp = NTC_Res2Temp(res_data_arr[NTC_EN].Res_value / 10);
    // TODO 临时设置为0
    can_packet_data->temp = 0;
}
